package csc.fresher.view;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import csc.fresher.entity.AccountHasInterestRate;
import csc.fresher.entity.AccountTransactionState;
import csc.fresher.entity.Customer;
import csc.fresher.entity.CustomerAccount;
import csc.fresher.entity.Transaction;
import csc.fresher.service.InterestRateService;
import csc.fresher.service.SavingAccountService;
import csc.fresher.service.SavingBookService;
import csc.fresher.service.SavingTransactionService;

@Component
@Scope("request")
public class SavingAccDetailManagedBean {

	@Autowired
	SavingAccManagedBean accManagedBean;
	@Autowired
	SavingBookService savingBookService;
	@Autowired
	InterestRateService interestRateService;
	@Autowired
	SavingTransactionService savingTransactionService;
	@Autowired
	SavingAccountService savingAccountService;

	private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();

	private CustomerAccount customerAccount;

	private Customer customer;

	private List<Transaction> txs;

	private List<AccountHasInterestRate> savingBook;

	private Date from;

	private Date to;

	private List<Transaction> checkedTxs;

	private String message;

	private Transaction selectedTx;

	public Transaction getSelectedTx() {
		return selectedTx;
	}

	public void setSelectedTx(Transaction selectedTx) {
		this.selectedTx = selectedTx;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public Map<Long, Boolean> getChecked() {
		return checked;
	}

	public void setChecked(Map<Long, Boolean> checked) {
		this.checked = checked;
	}

	public Date getFrom() {
		return from;
	}

	public void setFrom(Date from) {
		this.from = from;
	}

	public Date getTo() {
		return to;
	}

	public void setTo(Date to) {
		this.to = to;
	}

	public List<Transaction> getTxs() {
		return txs;
	}

	public List<AccountHasInterestRate> getSavingBook() {
		return savingBook;
	}

	public void setSavingBook(List<AccountHasInterestRate> savingBook) {
		this.savingBook = savingBook;
	}

	public void setTxs(List<Transaction> transactions) {
		this.txs = transactions;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public CustomerAccount getCustomerAccount() {
		return customerAccount;
	}

	public void setCustomerAccount(CustomerAccount customerAccount) {
		this.customerAccount = customerAccount;
	}

	public void loadTransactions() throws IOException {
		String uri = "ApproveTransaction.jsf";
		FacesContext.getCurrentInstance().getExternalContext().redirect(uri);
	}

	public void approveTx() {
		if (selectedTx != null) {
			System.out.println(selectedTx.getTransactionID());
			if (savingTransactionService.approveTransactionState(selectedTx
					.getTransactionID(), selectedTx.getCustomerAccountNumber(),
					accManagedBean.getSystemUser().getSystemUserID())) {
				message = "Approved Successfully!";
				redirect("savingAccView.jsf");
			}
		}
	}

	public void denyTx() {
		if (selectedTx != null) {
			System.out.println(selectedTx.getTransactionID());
			if (savingTransactionService.denyTransactionState(selectedTx
					.getTransactionID(), selectedTx.getCustomerAccountNumber(),
					accManagedBean.getSystemUser().getSystemUserID())) {
				message = "Denied Successfully!";
				redirect("savingAccView.jsf");
			}
		}
	}

	public void approve() {
		checkedTxs = new ArrayList<>();
		for (Transaction t : txs) {
			if (checked.get(t.getTransactionID()) != null) {
				if (checked.get(t.getTransactionID())) {
					checkedTxs.add(t);
					System.out.println(t.getTransactionID());
				}
			}
		}

		if (checkedTxs != null && checkedTxs.size() > 0) {
			for (Transaction tx : checkedTxs) {
				if (savingTransactionService.approveTransactionState(
						tx.getTransactionID(), tx.getCustomerAccountNumber(),
						accManagedBean.getSystemUser().getSystemUserID())) {
					message = "Approved Successfully!";
					redirect("savingAccView.jsf");
				} else {
					message = "Error has occurred.";
				}
			}
		}

	}

	public void deny() {
		checkedTxs = new ArrayList<>();
		for (Transaction t : txs) {
			if (checked.get(t.getTransactionID()) != null) {
				if (checked.get(t.getTransactionID())) {
					checkedTxs.add(t);
					System.out.println(t.getTransactionID());
				}
			}
		}

		if (checkedTxs != null && !checkedTxs.isEmpty()) {
			for (Transaction tx : checkedTxs) {
				if (savingTransactionService.denyTransactionState(
						tx.getTransactionID(), tx.getCustomerAccountNumber(),
						accManagedBean.getSystemUser().getSystemUserID())) {
					message = "Denied Successfully!";
					redirect("savingAccView.jsf");
				} else {
					message = "Error has occurred.";
				}
			}
		}

	}

	public void search() {
		if (from != null && to != null) {
			txs = savingTransactionService.getListTransactionAccountInAPeriod(
					customerAccount.getAccountNumber(),
					new Timestamp(from.getTime()), new Timestamp(to.getTime()));
			if(txs != null)
				System.out.println(txs.size());
			System.out.println(new Timestamp(from.getTime()));
			System.out.println(new Timestamp(to.getTime()));
		} else {
			message = "Please select a period of time you want to search.";
		}
	}
	
	public void changeRateBeforeExpiredDate(){
		if(savingAccountService.calculateProfitBeforeExpiredDate(customerAccount)){
			message = "Successfully!";
			redirect("savingAccView.jsf");
		}else{
			message = "Error has occurred.";
		}
	}

	@PostConstruct
	public void init() {
		txs = null;
		if (accManagedBean != null) {
			customerAccount = accManagedBean.getSelectedAccount();
			customerAccount = savingAccountService.getCustomerAccountByID(customerAccount.getAccountNumber());
			accManagedBean.setSelectedAccount(customerAccount);
			
			//Check status active 
			if ((customerAccount.getAccountTransactionState().getState()).
					equals(AccountTransactionState.ACTIVE.getState())) {
				accManagedBean.setActive(true);
			}else{
				accManagedBean.setActive(false);
			}
			
			customer = accManagedBean.getCustomer();
			if (customerAccount != null) {
				if (savingTransactionService != null) {
					txs = savingTransactionService
							.getListSavingTransactionByAccountNumber(customerAccount
									.getAccountNumber());
					for (Transaction t : txs) {
						System.out.println(t.getTransactionState());
					}
				} else {
					System.err.println("transaction service is null");
				}

				if (savingBookService != null) {
					if(customerAccount != null){
						System.out.println(customerAccount.getAccountBalance());
					} else {
						System.out.println("nulllll");
					}
					savingBook = savingBookService
							.getSavingBookByAccountNumber(customerAccount
									.getAccountNumber());
					if (savingBook != null) {
						System.err.println(savingBook.size());
						for (AccountHasInterestRate a : savingBook) {
							a.setInterestRate(interestRateService
									.getInterestRateByID(a.getInterestRateID()));
							System.out.println(interestRateService
									.getInterestRateByID(a.getInterestRateID()).getRate());
						}
					} else
						System.err.println("Saving book is null!");
				} else {
					System.err.println("Saving book service is null!");
				}
			}
		} else {
			System.err.println("Saving account managed bean is null!");
		}
	}
	
	private void redirect(String url) {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();
		try {
			externalContext.redirect(url);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
